package com.wc.算法基础课.B第二讲数据结构.散列表.星空之夜;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

/**
 * @Author congge
 * @Date 2024/3/21 16:10
 * @description https://www.acwing.com/problem/content/1404/
 */
public class Main {
    static FastReader sc = new FastReader();
    static PrintWriter out = new PrintWriter(System.out);
    static int N = 110;
    static char[][] g = new char[N][N];
    // 存连通块的所有点
    static int[][] points = new int[N * N][2];
    // 该哪一个字母了
    static int id = 0;
    // 误差
    static double eps = 1e-6;
    static int n, m;
    // 连通块的最后一个点
    static int end = 0;
    static double[] h = new double[N * N];

    public static void main(String[] args) {
        m = sc.nextInt();
        n = sc.nextInt();
        for (int i = 1; i <= n; i++) {
            g[i] = (" " + sc.next()).toCharArray();
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (g[i][j] == '1') {
                    end = 0;
                    dfs(i, j);
                    char c = getId(getHash());
                    paint(c);
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                out.print(g[i][j]);
            }
            out.println();
        }
        out.flush();
    }

    // 给每一个连通块涂色
    static void paint(char c) {
        for (int i = 1; i <= end; i++) {
            g[points[i][0]][points[i][1]] = c;
        }
    }

    // 欧式距离
    static double dis(int[] a, int[] b) {
        double dx = a[0] - b[0];
        double dy = a[1] - b[1];
        return Math.sqrt(dx * dx + dy * dy);
    }

    // 获得当前连通块所需要的字母
    static char getId(double key) {
        for (int i = 1; i <= id; i++) {
            if (Math.abs(h[i] - key) < eps) return (char) (i + 'a' - 1);
        }
        h[++id] = key;
        return (char) (id + 'a' - 1);
    }

    // 计算hash值
    static double getHash() {
        double sum = 0;
        for (int i = 1; i <= end; i++) {
            for (int j = i + 1; j <= end; j++) {
                sum += dis(points[i], points[j]);
            }
        }
        return sum;
    }

    // 寻找连通块
    static void dfs(int x, int y) {
        g[x][y] = '0';
        points[++end][0] = x;
        points[end][1] = y;
        for (int i = x - 1; i <= x + 1; i++) {
            for (int j = y - 1; j <= y + 1; j++) {
                if (i == x && j == y) continue;
                if (i >= 1 && i <= n && j >= 1 && j <= m && g[i][j] == '1') {
                    dfs(i, j);
                }
            }
        }
    }
}

class FastReader {
    StringTokenizer st;
    BufferedReader br;

    FastReader() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    String nextLine() {
        String s = "";
        try {
            s = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return s;
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    // 是否由下一个
    boolean hasNext() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                String line = br.readLine();
                if (line == null)
                    return false;
                st = new StringTokenizer(line);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return true;
    }
}
